/*
 * 项   目：learn-activiti
 * 作   者：罗毅（ymluo） 
 * 邮   箱：ymluo@iflytek.com
 * 创建时间：2017/9/22 9:22
 */
package com.roin.learn.activiti.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.pagehelper.util.StringUtil;
import com.roin.learn.activiti.base.BaseController;
import com.roin.learn.activiti.entity.ResourceResult;
import com.roin.learn.activiti.service.ProcessService;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import java.util.List;

import static org.activiti.editor.constants.ModelDataJsonConstants.MODEL_DESCRIPTION;
import static org.activiti.editor.constants.ModelDataJsonConstants.MODEL_NAME;

/**
 * 流程模型Controller
 * @version 1.0
 * @author 罗毅(ymluo)
 * @date 2017-09-22 09:23
 */

@RequestMapping("process/model")
@Controller
public class ProcessModelController extends BaseController {

    @Resource
    ProcessService processService;
    @Resource
    RepositoryService repositoryService;
    @Resource
    private ObjectMapper objectMapper;
    /**
     * 转到模型列表页面
     * @return
     */
    @RequestMapping("")
    public ModelAndView toModel(){
        ModelAndView mav = new ModelAndView("process/model");
        List<Model> models = processService.queryModel(null);
        mav.addObject("models",models);
        return mav;
    }


    /**
     * 新建模型
     * @param name 模型名称
     * @return com.roin.learn.activiti.entity.ResourceResult
     * @throws
     * @author 罗毅(ymluo)
     * @date 2017-09-22 09:28
     */
    @RequestMapping("add.do")
    @ResponseBody
    public ResourceResult add(String name) {
        ResourceResult result = new ResourceResult();
        if (StringUtil.isEmpty(result.getMessage())) {
            try {
                if (StringUtils.isEmpty(name))
                    name = "name";
                Model model  = repositoryService.newModel();
                model.setName(name);
                model.setKey("key");
                ObjectNode modelObjectNode = objectMapper.createObjectNode();
                modelObjectNode.put(MODEL_NAME, name);
                modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
                modelObjectNode.put(MODEL_DESCRIPTION, name);
                model.setMetaInfo(modelObjectNode.toString());
                //保存模型
                repositoryService.saveModel(model);

                ObjectNode editorNode = objectMapper.createObjectNode();
                editorNode.put("id", "canvas");
                editorNode.put("resourceId", "canvas");
                ObjectNode stencilSetNode = objectMapper.createObjectNode();
                stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
                editorNode.set("stencilset", stencilSetNode);
                repositoryService.addModelEditorSource(model.getId(), editorNode.toString().getBytes("utf-8"));
                
                result.setSuccess(true).setMessage("创建成功！").setData(model.getId());
            }catch (Exception e){
                result.setMessage("创建失败!信息："+e.getMessage());
            }

        }
        return result;

    }
    /**
     * 删除模型
     * @param id
     * @return
     */
    @RequestMapping("delete.do")
    @ResponseBody
    public ResourceResult deleteModel(String id) {
        ResourceResult result = new ResourceResult();
        if (StringUtils.isEmpty(id))
            result.setMessage( "删除失败!id参数为空！");
        if (StringUtil.isEmpty(result.getMessage())) {
            try {
                processService.deleteModel(id);
                result.setSuccess(true);
                result.setMessage("删除成功！");
            }catch (Exception e){
                result.setMessage("删除失败!信息："+e.getMessage());
            }

        }
        return result;

    }
    /**
     * 通过模型发布（部署）流程定义
     * @param id
     * @return
     */
    @RequestMapping("deploy.do")
    @ResponseBody
    public ResourceResult deployModel(String id) {
        ResourceResult result = new ResourceResult();
        if (StringUtils.isEmpty(id))
            result.setMessage( "发布失败!id参数为空！");
        if (StringUtil.isEmpty(result.getMessage())) {
            try {
                Model modelData = repositoryService.getModel(id);
                byte[] bytes = repositoryService.getModelEditorSource(modelData.getId());

                if (bytes == null) {
                    result.setMessage("模型数据为空，请先设计流程并成功保存，再进行发布。");
                    return result;
                }

                JsonNode modelNode = (JsonNode) new ObjectMapper().readTree(bytes);
                byte[] bpmnBytes = null;

                BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
                bpmnBytes = new BpmnXMLConverter().convertToXML(model);

                String processName = modelData.getName() + ".bpmn20.xml";
                Deployment deployment = repositoryService.createDeployment()
                        .name(modelData.getName())
                        .addString(processName, new String(bpmnBytes, "UTF-8")).deploy();
                modelData.setDeploymentId(deployment.getId());
                repositoryService.saveModel(modelData);
                result.setSuccess(true).setMessage("发布成功！");
            }catch (Exception e){
                result.setMessage("发布失败!信息："+e.getMessage());
            }

        }
        return result;

    }
}
